<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <button @click="count0++">{{count}}</button>
  </div>
  <script type="module">
    import { createApp, ref, onMounted, onUpdated, onUnmounted, onBeforeMount, onBeforeUpdate, onBeforeUnmount, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated } from 'https://lib.baomitu.com/vue/3.2.31/vue.esm-browser.js'
    createApp({
      setup() {
        console.log('setup')
        const count = ref(0)

        // 注意，所有的在本页的 API 都应该在组件的 `setup()` 阶段被同步调用
        onBeforeMount(() => {
          // 组件被挂载之前被调用
          // 当这个钩子被调用时，组件已经完成了其响应式状态的设置，但是还没有创建 DOM 节点
          console.log('onBeforeMount in setup()')
        })
        onMounted(() => {
          // 注册一个在组件挂载完成后执行的回调函数
          // 组件在以下情况被视为已挂载
          //   1. 所有同步子组件都已经被挂载(不包含异步组件或者 <Suspense> 树内的组件)
          //   2. 他的 DOM 树已经被创建并插入到父容器中，注意，只有当应用程序的跟容器也在文档中时，才能保证组件的 DOM 树也在文档中
          // 这个钩子函数常用于需要访问到组件已经渲染好的 DOM 元素时, 或是为了在一个 服务端渲染应用 中限制 DOM 相关的代码
          // 服务器端渲染期间不会被调用
          console.log('onMounted in setup()')
        })
        onBeforeUpdate(() => {
          // 因为响应式状态改变而更新 DOM 树之前调用
          console.log('onBeforeUpdate in setup()')
        })
        onUpdated(() => {
          // 注册一个回调函数，在组件由于响应式状态改变而更新了 DOM 树后调用
          // 父组件的更新钩子会在其子组件的更新钩子调用后调用
          // 如果需要在特定的状态改变后访问更新好的 DOM , 可以使用 nextTick()
          // 注意: 不要再更新的钩子中改变组件的状态, 有可能会造成无限的更新循环
          console.log('onUpdated in setup()')
        })
        onBeforeUnmount(() => {
          // 组件实例被卸载之前被调用
          console.log('onBeforeUnmount in setup()')
        })
        onUnmounted(() => {
          // 注册一个要在组件卸载后调用的回调
          // 组件再以下情况下被认为是卸载的：
          //   1. 它的所有子组件都已经卸载
          //   2. 所有相关的响应式副作用（渲染效果和再 setup() 创建的计算属性/监听器）都已停止
          // 作用：可以使用此钩子清空手动创建副作用，定时器，DOM 事件监听器或者服务器连接
          console.log('onUnmounted in setup()')
        })
        onErrorCaptured((errorObject, componentInstance, errorInfoStr) => {
          // 当从下级组件抛上来的错误被捕获时被调用
          console.log('onErrorCaptured in setup()', errorObject, componentInstance, errorInfoStr)
        })
        onRenderTracked(() => {
          // 仅再开发模式下可用，当组件的渲染效果跟踪了一个响应式依赖时被调用
          console.log('onRenderTracked in setup()')
        })
        onRenderTriggered(() => {
          // 仅在开发模式下可用，当响应性依赖触发组件的渲染效果重新运行时调用
          console.log('onRenderTriggered in setup()')
        })
        onActivated(() => {
          // 组件实例作为树的一部分被 <KeepAlive> 缓存，被插入到 DOM 中时调用。
        })
        onDeactivated(() => {
          // 当组件实例作为树的一部分被 <KeepAlive> 缓存，从 DOM 中移除时调用。
        })

        return {
          count
        }
      },
      beforeCreate() {
        console.log('beforeCreate')
      },
      created() {
        console.log('created')
      },
      beforeMount() {
        console.log('beforeMount')
      },
      mounted() {
        console.log('mounted')
      },
      beforeUpdate() {
        console.log('beforeUpdate')
      },
      updated() {
        console.log('updated')
      },
      beforeUnmount() {
        console.log('beforeUnmount')
      },
      unmounted() {
        console.log('unmounted')
      },
      errorCaptured() {
        console.log('errorCaptured')
      },
      renderTracked() {
        console.log('renderTracked')
      },
      actived() {
        console.log('actived')
      },
      deactived() {
        console.log('deactived')
      }
    }).mount('#app')
  </script>
</body>
</html>